<script setup lang="ts">
import { computed, ref, watch } from 'vue';
import { message } from 'ant-design-vue';
import { fetchGetRoleMenuButtonTree, fetchUpdateRoleMenuButtonPermissions } from '@/service/api/system-manage';

interface Props {
  roleId: number;
}

const props = defineProps<Props>();

const emit = defineEmits<{
  (e: 'saved'): void;
}>();

const visible = defineModel<boolean>('open', {
  default: false
});

// 状态管理
const loading = ref(false);
const menuTreeData = ref<any[]>([]);
const checkedMenuKeys = ref<string[]>([]);
const currentMenuKey = ref<string | null>(null);
const availableButtons = ref<string[]>([]);
const checkedButtonKeys = ref<string[]>([]);

// 按钮权限映射：menuId -> buttonCodes[]
const buttonMap = ref<Record<string, string[]>>({});

// 计算属性

const currentMenu = computed(() => {
  if (!currentMenuKey.value) return null;
  return findMenuByKey(menuTreeData.value, currentMenuKey.value);
});

const buttonOptions = computed(() => {
  return availableButtons.value.map(buttonCode => ({
    label: getButtonDisplayName(buttonCode),
    value: buttonCode
  }));
});

// 获取菜单按钮权限树
async function loadMenuButtonTree() {
  try {
    console.log('开始加载菜单按钮权限树，角色ID:', props.roleId);

    const response = (await fetchGetRoleMenuButtonTree(props.roleId)) as any;

    // 检查响应格式 - 适配不同的响应格式
    let data;

    if (Boolean(response) && response.menuTree !== undefined) {
      // 直接数据格式：response 就是数据本身
      data = response;
    } else if (Boolean(response && response.data) && response.data.menuTree !== undefined) {
      // 包装格式：{data: {...}}
      data = response.data;
    } else if (Boolean(response && response.code) && response.code === '0000' && response.data) {
      // 标准格式：{code: "0000", data: {...}}
      data = response.data;
    } else {
      console.error('API响应格式错误:', response);
      console.error('响应结构分析:', {
        hasResponse: Boolean(response),
        hasData: Boolean(response && response.data),
        hasMenuTree: Boolean(response && response.menuTree),
        hasCode: Boolean(response && response.code),
        responseKeys: response ? Object.keys(response) : []
      });
      window.$message?.error('获取菜单按钮权限树失败：响应格式错误');
      return;
    }

    // 转换菜单树数据
    menuTreeData.value = transformMenuTree(data.menuTree || []);

    // 验证并清理选中的菜单 key，确保它们存在于菜单树中
    const allMenuKeys = getAllMenuKeys(menuTreeData.value);

    const validCheckedKeys = (data.checkedMenuKeys || []).filter((key: string) => allMenuKeys.includes(key));

    if (validCheckedKeys.length !== (data.checkedMenuKeys || []).length) {
      console.warn('发现无效的菜单 key，已自动清理:', {
        original: data.checkedMenuKeys || [],
        valid: validCheckedKeys,
        invalid: (data.checkedMenuKeys || []).filter((key: string) => !allMenuKeys.includes(key))
      });
    }

    checkedMenuKeys.value = validCheckedKeys;
    buttonMap.value = data.buttonMap || {};

    // 设置当前菜单为第一个已选菜单
    if (checkedMenuKeys.value.length > 0) {
      currentMenuKey.value = checkedMenuKeys.value[0];
      console.log('设置当前菜单:', currentMenuKey.value);
    } else {
      console.log('没有选中的菜单');
    }
  } catch (error: any) {
    console.error('获取菜单按钮权限树失败:', error);
    message.error('获取菜单按钮权限树失败');
  }
}

// 转换菜单树数据
function transformMenuTree(menus: any[]): any[] {
  return menus.map(menu => ({
    ...menu,
    key: String(menu.id),
    title: menu.menuName,
    menuType: menu.menuType || '1', // 确保 menuType 字段存在
    children: menu.children ? transformMenuTree(menu.children) : undefined
  }));
}

// 处理菜单选择
function handleMenuCheck(checkedKeys: any) {
  const keys = Array.isArray(checkedKeys) ? checkedKeys : checkedKeys.checked;
  checkedMenuKeys.value = keys.map((key: any) => String(key));

  // 如果当前菜单被取消选中，切换到下一个已选菜单
  if (currentMenuKey.value && !keys.includes(currentMenuKey.value)) {
    currentMenuKey.value = keys[0] || null;
  }

  // 清空未选菜单的按钮权限
  for (const key in buttonMap.value) {
    if (!keys.includes(key)) {
      buttonMap.value[key] = [];
    }
  }
}

// 处理菜单点击选择
function handleMenuSelect(selectedKeys: any[]) {
  if (selectedKeys.length > 0) {
    const selectedKey = String(selectedKeys[0]);
    currentMenuKey.value = selectedKey;
  }
}

// 监听当前菜单变化
watch(currentMenuKey, key => {
  if (key) {
    const menu = findMenuByKey(menuTreeData.value, key);
    if (menu) {
      // 解析菜单的按钮权限
      if (menu.buttons) {
        try {
          availableButtons.value = JSON.parse(menu.buttons);
        } catch (error: any) {
          console.error('解析菜单按钮权限失败:', error);
          availableButtons.value = [];
        }
      } else {
        console.log('菜单没有配置按钮权限');
        availableButtons.value = [];
      }

      // 获取当前角色在该菜单下的按钮权限
      checkedButtonKeys.value = buttonMap.value[key] || [];
    }
  } else {
    console.log('清空按钮权限');
    availableButtons.value = [];
    checkedButtonKeys.value = [];
  }
});

// 监听按钮权限变化
watch(checkedButtonKeys, val => {
  if (currentMenuKey.value) {
    buttonMap.value[currentMenuKey.value] = val;
  }
});

// 全选按钮权限
function handleSelectAll() {
  checkedButtonKeys.value = [...availableButtons.value];
}

// 清空按钮权限
function handleClear() {
  checkedButtonKeys.value = [];
}

// 获取按钮显示名称
function getButtonDisplayName(buttonCode: string): string {
  const buttonNameMap: Record<string, string> = {
    USER_ADD: '新增用户',
    USER_EDIT: '编辑用户',
    USER_DELETE: '删除用户',
    USER_VIEW: '查看用户',
    ROLE_ADD: '新增角色',
    ROLE_EDIT: '编辑角色',
    ROLE_DELETE: '删除角色',
    ROLE_VIEW: '查看角色',
    MENU_ADD: '新增菜单',
    MENU_EDIT: '编辑菜单',
    MENU_DELETE: '删除菜单',
    MENU_VIEW: '查看菜单',
    TENANT_ADD: '新增租户',
    TENANT_EDIT: '编辑租户',
    TENANT_DELETE: '删除租户',
    TENANT_VIEW: '查看租户',
    LOG_VIEW: '查看日志',
    MQ_SEND: '发送消息',
    MQ_RECEIVE: '接收消息',
    NODE_ADD: '新增节点',
    NODE_EDIT: '编辑节点',
    TASK_ADD: '新增任务',
    TASK_EDIT: '编辑任务',
    TASK_EXECUTE: '执行任务',
    B_CODE1: '超级管理员可见按钮',
    B_CODE2: '管理员可见按钮',
    B_CODE3: '管理员或用户可见按钮'
  };

  return buttonNameMap[buttonCode] || buttonCode;
}

// 递归查找菜单
function findMenuByKey(menus: any[], key: string): any | null {
  for (const menu of menus) {
    if (menu.key === key) {
      return menu;
    }
    if (menu.children) {
      const found = findMenuByKey(menu.children, key);
      if (found) return found;
    }
  }
  return null;
}

// 递归获取所有菜单的 key
function getAllMenuKeys(menus: any[]): string[] {
  const keys: string[] = [];
  for (const menu of menus) {
    keys.push(menu.key);
    if (menu.children) {
      keys.push(...getAllMenuKeys(menu.children));
    }
  }
  return keys;
}

// 保存权限配置
async function handleSave() {
  loading.value = true;
  try {
    const response = (await fetchUpdateRoleMenuButtonPermissions(props.roleId, {
      menuIds: checkedMenuKeys.value,
      buttonMap: buttonMap.value
    })) as any;

    // 检查响应格式 - 适配不同的响应格式
    let success = false;
    let responseMessage = '';

    if (response && response.code === '0000') {
      // 标准格式：{code: "0000", msg: "..."}
      success = true;
      responseMessage = response.msg || '权限配置保存成功';
      console.log('使用标准响应格式');
    } else if (response && response.data && response.data.code === '0000') {
      // 包装格式：{data: {code: "0000", msg: "..."}}
      success = true;
      responseMessage = response.data.msg || '权限配置保存成功';
      console.log('使用包装响应格式');
    } else if (response && response.response && response.response.data && response.response.data.code === '0000') {
      // 多层包装格式：{data: undefined, error: null, response: {data: {code: "0000", msg: "..."}}}
      success = true;
      responseMessage = response.response.data.msg || '权限配置保存成功';
      console.log('使用多层包装响应格式');
    } else if (response && response.msg) {
      // 直接消息格式：{msg: "..."}
      responseMessage = response.msg;
      console.log('使用直接消息格式');
    } else {
      responseMessage = '保存失败';
      console.log('响应格式无法识别');
    }

    if (success) {
      window.$message?.success(responseMessage);
      emit('saved');
      closeModal();
    } else {
      window.$message?.error(responseMessage);
    }
  } catch (error: any) {
    console.error('保存权限配置失败:', error);
    window.$message?.error('保存权限配置失败');
  } finally {
    loading.value = false;
  }
}

// 关闭弹窗
function closeModal() {
  visible.value = false;
  checkedMenuKeys.value = [];
  currentMenuKey.value = null;
  availableButtons.value = [];
  checkedButtonKeys.value = [];
  buttonMap.value = {};
}

// 监听弹窗显示状态
watch(visible, val => {
  if (val && props.roleId) {
    console.log('开始加载菜单按钮权限树...');
    loadMenuButtonTree();
  } else {
    console.log('重置数据...');
    // 重置数据
    menuTreeData.value = [];
    checkedMenuKeys.value = [];
    currentMenuKey.value = null;
    availableButtons.value = [];
    checkedButtonKeys.value = [];
    buttonMap.value = {};
  }
});
</script>

<template>
  <AModal
    v-model:open="visible"
    title="分配菜单与按钮权限"
    width="900px"
    :confirm-loading="loading"
    @ok="handleSave"
    @cancel="closeModal"
  >
    <div class="menu-button-auth-modal">
      <!-- 左侧：菜单树 -->
      <div class="menu-tree">
        <div class="menu-header">
          <ATypographyText strong>菜单权限</ATypographyText>
          <ATypographyText type="secondary" style="margin-left: 8px">（勾选菜单后可配置其下按钮权限）</ATypographyText>
        </div>
        <ATree
          v-model:checked-keys="checkedMenuKeys"
          :tree-data="menuTreeData"
          checkable
          show-line
          :field-names="{ title: 'title', key: 'key', children: 'children' }"
          @check="handleMenuCheck"
          @select="handleMenuSelect"
        >
          <template #title="{ title, record }">
            <span>{{ title }}</span>
            <ATag v-if="record && record.menuType === '2'" size="small" color="blue" style="margin-left: 8px">
              页面
            </ATag>
          </template>
        </ATree>

        <!-- 调试信息 -->
        <div
          v-if="menuTreeData.length === 0"
          style="margin-top: 16px; padding: 16px; background: #f5f5f5; border-radius: 4px"
        >
          <ATypographyText type="secondary">调试信息：菜单树数据为空</ATypographyText>
          <br />
          <ATypographyText type="secondary" style="font-size: 12px">角色ID: {{ props.roleId }}</ATypographyText>
        </div>
      </div>

      <!-- 右侧：按钮权限 -->
      <div class="button-permission">
        <div v-if="currentMenu" class="button-content">
          <div class="button-header">
            <ATypographyText strong>【{{ currentMenu.title }}】按钮权限</ATypographyText>
            <ASpace>
              <AButton type="link" size="small" @click="handleSelectAll">全选</AButton>
              <AButton type="link" size="small" @click="handleClear">清空</AButton>
            </ASpace>
          </div>

          <div v-if="availableButtons.length > 0" class="button-list">
            <ACheckboxGroup v-model:value="checkedButtonKeys" :options="buttonOptions as any" />
          </div>

          <div v-else class="no-buttons">
            <ATypographyText type="secondary">该菜单暂未配置按钮权限</ATypographyText>
          </div>
        </div>

        <div v-else class="no-menu-selected">
          <div class="empty-state">
            <AEmpty description="请先选择左侧菜单以配置按钮权限" :image-style="{ height: '80px' }" />
          </div>
        </div>
      </div>
    </div>
  </AModal>
</template>

<style scoped>
.menu-button-auth-modal {
  display: flex;
  gap: 24px;
  min-height: 400px;
}

.menu-tree {
  flex: 1 1 0;
  min-width: 280px;
  max-width: 350px;
  border-right: 1px solid #f0f0f0;
  padding-right: 16px;
}

.menu-header {
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #f0f0f0;
}

.button-permission {
  flex: 2 1 0;
  padding-left: 16px;
}

.button-content {
  height: 100%;
  display: flex;
  flex-direction: column;
}

.button-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 16px;
  padding-bottom: 8px;
  border-bottom: 1px solid #f0f0f0;
}

.button-list {
  flex: 1;
  overflow-y: auto;
}

.no-buttons,
.no-menu-selected {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
  color: #999;
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 300px;
}
</style>
